package com.nobody.facepk.service;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nobody.facepk.dao.PictureDao;
import com.nobody.facepk.model.Friends;
import com.nobody.facepk.model.Match;
import com.nobody.facepk.model.MatchData;
import com.nobody.facepk.model.MatchDataType;
import com.nobody.facepk.model.Message;
import com.nobody.facepk.model.Picture;
import com.nobody.facepk.model.PictureData;
import com.nobody.facepk.model.PictureDataType;
import com.nobody.facepk.model.PictureState;
import com.nobody.facepk.model.User;
import com.nobody.facepk.model.UserData;
import com.nobody.facepk.model.UserDataType;
import com.nobody.facepk.pojo.MatchDataHelper;
import com.nobody.facepk.pojo.PictureDataHelper;
import com.nobody.facepk.pojo.UserDataHelper;
import com.nobody.facepk.pojo.json.MatchPoll;
import com.nobody.facepk.pojo.json.Scoring;
import com.nobody.facepk.pojo.json.Types;
import com.nobody.facepk.sns.Event;
import com.nobody.facepk.sns.EventType;
import com.nobody.facepk.utils.UserUtils;
import com.trg.dao.hibernate.GeneralDAO;

@Service
public class PictureService {
	private GeneralDAO   generalDao;
	private PictureDao   pictureDao;
	private UserService  userService;
	private EventService eventService;
	
	@Transactional(readOnly=false)
	public void addPicture(Long userId, String path) {
		Picture picture = new Picture();
		picture.setCreateTime(new Date(System.currentTimeMillis()));
		picture.setUserId(userId);
		picture.setPath(path);
		picture.setScore(5);
		picture.setState(PictureState.INIT);
		this.generalDao.save(picture);
		ServiceRegistry.getPictureManager().addNewPicture(picture.getId());
	}
	
	@Transactional(readOnly=true)
	public List<Picture> getPictures(Long userId){
		return this.pictureDao.getPictures(userId);
	}
	
	@Transactional(readOnly=true)
	public List<Picture> getMyScoringPictures(Long userId){
		return this.pictureDao.getScoringPictures(userId);
	}
	
	@Transactional(readOnly=true)
	public List<Picture> getMyInitPictures(Long userId){
		return this.pictureDao.getMyInitPictures(userId);
	}
	
	@Transactional(readOnly=false)
	public void score(Long userId, Long pictureId, int score){
		User user = this.generalDao.find(User.class, userId);
		Picture picture = this.generalDao.find(Picture.class, pictureId);
		int voteCount = picture.getScoreCount();
		int totalScore = picture.getScore()*voteCount;
		if(totalScore==0) totalScore = 5;
		int newScore = totalScore/(voteCount+1);
		picture.setScoreCount(voteCount+1);
		picture.setScore(newScore);
		this.generalDao.save(picture);
		
		String content = user.getName()+" 为您的照片评分:"+score;
		Message message = new Message(picture.getUserId(),content);
		this.generalDao.save(message);
	}
	
	@Transactional(readOnly=false)
	public void grade(Long userId, Long pictureId){
		User user = this.generalDao.find(User.class, userId);
		Picture picture = this.generalDao.find(Picture.class, pictureId);
		if(picture.getState().equals(PictureState.INIT)){  //如果还没有被评分
			picture.setState(PictureState.SCORING);
			this.generalDao.save(picture);
			UserData userData = user.getUserData(UserDataType.RECENT_PICTURES);
			if(userData == null){
				userData = new UserData(user.getId(), UserDataType.RECENT_PICTURES);
				List<Long> pics = new ArrayList<Long>();
				pics.add(pictureId);
				userData.setData(pics);
			}else{
				List<Long> pics = userData.getDataAsList(Types.LONG_LIST);
				pics.add(pictureId);
				userData.setData(pics);
			}
			this.generalDao.save(userData);
			//发起新鲜事
			Event event = new Event(userId,EventType.SCORE_CANDIDATE,pictureId);
			eventService.handleEvent(event);
		
		}
	}
	
	//获取我的好友正在评分的照片
	@Transactional(readOnly=false)
	public List<Picture> getFriendsScoringPic(Long userId){
		List<Picture> scoringPic = new ArrayList<Picture>();
		//获取好友列表
		Friends friends = userService.getMyFriends(userId);
		Set<Long> friendIds = friends.getFriendIds();
		for(long friendId : friendIds){ //循环出我的好友ID
//			UserData userData = UserDataHelper.getUserData(friendId, UserDataType.RECENT_PICTURES);
//			if(userData != null){
//				List<Long> pics = userData.getDataAsList(Types.LONG_LIST);
//				for(long picId : pics){
//					Picture picture = this.generalDao.find(Picture.class, picId);
//					scoringPic.add(picture);
//				}
//			}
			
			List<Picture> scoringList = this.pictureDao.getScoringPictures(friendId);
			if(scoringList!=null){
				if(scoringList.size() > 0 ){
					
					scoringPic.addAll(scoringList);
				}
			}
		}
		return scoringPic;
	}
	
	@Transactional(readOnly=false)
	public List<Picture> getFriendsEndScoringPic(Long userId){
		List<Picture> endScoringPic = new ArrayList<Picture>();
		UserData userData = UserDataHelper.getUserData(userId, UserDataType.RECENT_ENDSCORING);
		//获取我最近评分完成的照片集合
		if(userData != null){
			List<Long> pics = userData.getDataAsList(Types.LONG_LIST);
			for(long picId : pics){
				//获取已经完成评分的ID集合
				Picture picture = this.generalDao.find(Picture.class, picId);
				endScoringPic.add(picture);
			}
		}
		
		//获取好友列表
		Friends friends = userService.getMyFriends(userId);
		Set<Long> friendIds = friends.getFriendIds();
		for(long friendId : friendIds){ //循环出我的好友ID
			UserData friendData = UserDataHelper.getUserData(friendId, UserDataType.RECENT_ENDSCORING);
			if(friendData != null){
				List<Long> pics = friendData.getDataAsList(Types.LONG_LIST);
				for(long picId : pics){
					//获取已经完成评分的ID集合
					Picture picture = this.generalDao.find(Picture.class, picId);
					endScoringPic.add(picture);
				}
			}
		}
		return endScoringPic;
	}
	
	@Transactional(readOnly=true)
	public Picture getPictureByid(Long pictureId){
		return this.generalDao.find(Picture.class, pictureId);
	}
	
	@Transactional(readOnly=true)
	public Match getMatchByid(Long matchId){
		return this.generalDao.find(Match.class, matchId);
		
	}
	
	
	@Transactional(readOnly=false)
	public List<User> getScoredUserByPicId(Long picId){
		PictureData data = PictureDataHelper.getPictureData(picId, PictureDataType.SCORINGS);
		List<User> users = new ArrayList<User>();
		if(data != null){
			List<Scoring> scoring = data.getDataAsList(Scoring.LIST_TYPE);
			for(int i = 0 ; i < scoring.size() ; i ++){
				Scoring  s = (Scoring)scoring.get(i);
				long userId = s.getUserId();
				User user = this.userService.getUserById(userId);
				if(user != null){
					users.add(user);
				}
			}
		}
		return users;
	}
	
	
	@Transactional(readOnly=false)
	public boolean scoring(Picture pic,int score){
		boolean isScored = false;
		Long userId = UserUtils.getUserId();
		User user = this.generalDao.find(User.class, userId);
		
		User targetUser = this.generalDao.find(User.class, pic.getUserId());
		
		int count_ = pic.getScoreCount();
		int score_ = pic.getScore();
		int nowCount = count_+1;
		int nowScore = (score+(count_*score_))/nowCount;
		
		
		//首先检查这个照片自己是否已经打分了
		PictureData data = PictureDataHelper.getPictureData(pic.getId(), PictureDataType.SCORINGS);
		if(data != null){
			List<Scoring> scoring = data.getDataAsList(Scoring.LIST_TYPE);
			for(int i = 0 ; i < scoring.size() ; i ++){
				Scoring  s = (Scoring)scoring.get(i);
				if(s.getUserId().equals(userId)){
					isScored  =true;
					break;
				}
			}
		}
		if(!isScored){
			try{
				pic.setScoreCount(nowCount);
				pic.setScore(nowScore);
				if(nowCount>=10){  //关闭
					pic.setState(PictureState.FREE);
					//记录最近投票结束信息
					PictureData pd = PictureDataHelper.getPictureData(pic.getId(), PictureDataType.ENDSCORING);
					if(pd != null){
					}else{
						pd = new PictureData(pic.getId(), PictureDataType.ENDSCORING);
						List<Long> list = new ArrayList<Long>();
						list.add(pic.getId());
						pd.setData(list);
						this.generalDao.save(pd);
					}
					//投票人增加最近投票结束记录
					UserData userData = UserDataHelper.getUserData(user.getId(), UserDataType.RECENT_ENDSCORING);
					if(userData != null){
						List<Long> list = userData.getDataAsList(Types.LONG_LIST);
						if(!list.contains(pic.getId())){
							list.add(pic.getId());
							userData.setData(list);
							this.generalDao.save(userData);
						}
					}else{
						userData = new UserData(user.getId(), UserDataType.RECENT_ENDSCORING);
						List<Long> list = new ArrayList<Long>();
						list.add(pic.getId());
						userData.setData(list);
						this.generalDao.save(userData);
					}
					//发起新鲜事
					Event event = new Event(userId,EventType.END_SCORING,pic.getId());
					eventService.handleEvent(event);
				}
				this.generalDao.save(pic);
				//添加消息列表
				String content = user.getName()+" 为您的照片评分:"+score;
				Message message = new Message(pic.getUserId(),content);
				this.generalDao.save(message);
				//Scoring对象
				Scoring s= new Scoring();
				s.setPictureId(pic.getId());
				s.setScore(score);
				s.setTime(System.currentTimeMillis());
				s.setUserId(userId);
				
				//记录投票信息
				PictureData pd = PictureDataHelper.getPictureData(pic.getId(), PictureDataType.SCORINGS);
				if(pd != null){
					List<Scoring> scoring = pd.getDataAsList(Scoring.LIST_TYPE);
					scoring.add(s);
					pd.setData(scoring);
					this.generalDao.save(pd);
				}else{
					pd = new PictureData(pic.getId(), PictureDataType.SCORINGS);
					List<Scoring> scoring = new ArrayList<Scoring>();
					scoring.add(s);
					pd.setData(scoring);
					this.generalDao.save(pd);
				}
				//投票人增加最近投票记录
				UserData userData = UserDataHelper.getUserData(user.getId(), UserDataType.RECENT_SCORINGS);
				if(userData != null){
					List<Scoring> scoring = userData.getDataAsList(Scoring.LIST_TYPE);
					scoring.add(s);
					userData.setData(scoring);
					this.generalDao.save(userData);
				}else{
					userData = new UserData(user.getId(), UserDataType.RECENT_SCORINGS);
					List<Scoring> scoring = new ArrayList<Scoring>();
					scoring.add(s);
					userData.setData(scoring);
					this.generalDao.save(userData);
				}
				//发起新鲜事
				Event event = new Event(userId,EventType.SCORING,pic.getId());
				eventService.handleEvent(event);
				return true;
			}catch(Exception e){
				e.printStackTrace();
				return false;
			}
		}else{
			return false;
		}
	}
	
	@Transactional(readOnly=false)
	public List<Picture> choosePic(Long userId,Picture pic){
		List picList = this.pictureDao.getNearlyMatchPic(userId,pic,3); //取出3张
		return picList;
	}
	
	@Transactional(readOnly=false)
	public List<Picture> getFreePicturesById(Long userId){
		return this.pictureDao.getFreePictures(userId);
	}
	
	@Transactional(readOnly=false)
	public boolean match(Picture pic,Picture targetPic){
		Long userId = UserUtils.getUserId();
		User user = this.generalDao.find(User.class, userId);
		//先判断PK条件是否满足
		if(pic.getState() == PictureState.FREE 
				&& targetPic.getState() == PictureState.FREE
				&& pic.getSex() == targetPic.getSex() ){ //满足要求 可以PK
				//设置我的照片的状态是PK中
				pic.setState(PictureState.MATCH);
				targetPic.setState(PictureState.MATCH);
				this.generalDao.save(pic);
				this.generalDao.save(targetPic);
				//先在比赛表中添加一条数据
				Match match = new Match();
				match.setHostId(pic.getId());
				match.setHostWins(0);
				match.setGuestId(targetPic.getId());
				match.setGuestWins(0);
				match.setTime(System.currentTimeMillis());
				this.generalDao.save(match);
				//投票人增加最近Pk记录
				UserData userData = UserDataHelper.getUserData(user.getId(), UserDataType.RECENT_MATCH);
				if(userData != null){
					List<Long> Matches = userData.getDataAsList(Types.LONG_LIST);
					Matches.add(match.getId());
					userData.setData(Matches);
					this.generalDao.save(userData);
				}else{
					userData = new UserData(user.getId(), UserDataType.RECENT_MATCH);
					List<Long> Matches = new ArrayList<Long>();
					Matches.add(match.getId());
					userData.setData(Matches);
					this.generalDao.save(userData);
				}
				//发起新鲜事
				Event event = new Event(userId,EventType.VERSUS,match.getId());
				eventService.handleEvent(event);
				return true;
			
		}else{
			return false;
		}
	}
	//最近发起的PK
	@Transactional(readOnly=false)
	public List<Match> getUserMatchIds(Long userId){
		//User user = this.generalDao.find(User.class, userId);
		UserData userData = UserDataHelper.getUserData(userId, UserDataType.RECENT_MATCH);
		if(userData != null){
			return userData.getDataAsList(Types.LONG_LIST);
		}else{
			return null;
		}
	}
	//最近完成的PK
	@Transactional(readOnly=false)
	public List<Match> getUserEndMatchIds(Long userId){
		//User user = this.generalDao.find(User.class, userId);
		UserData userData = UserDataHelper.getUserData(userId, UserDataType.RECENT_ENDMATCH);
		if(userData != null){
			return userData.getDataAsList(Types.LONG_LIST);
		}else{
			return null;
		}
	}
	
	
	@Transactional(readOnly=false)
	public boolean poll(Long userId,Long matchId , Long picId){
		//0 首先判断此PK是否已经结束
		Match m = (Match)this.generalDao.find(Match.class, matchId);
		long  startTimes = m.getTime();
		if(System.currentTimeMillis() < startTimes+24*(1000*3600)){
			// 1 验证 我是否已经对此照片投票了
			// 2 如果投票了 要看我这次投票时间够没
			boolean Poll = false;
			MatchData matchData = MatchDataHelper.getMatchData(matchId, MatchDataType.POLLS);
			if(matchData != null){
				List<MatchPoll> list = (List)matchData.getDataAsList(MatchPoll.LIST_TYPE);
				for(MatchPoll mp:list){
					if(mp.getMatchId().equals(matchId)){ //首先找到这场比赛的记录
						if(System.currentTimeMillis() >(long)mp.getTime()+(1000*3600)){//时间到了 可以投票
							Poll = true;
							break;
						}
					}
				}
			}else{
				Poll = true;
			}
			// 3 如果时间够了  那么修改投票记录
			if(Poll){
				if(picId == m.getHostWins()){//是支持发起人的
					int hostWin = m.getHostWins();
					m.setHostWins(hostWin++);
				}else if(picId == m.getGuestWins()){
					int guestWin = m.getGuestWins();
					m.setGuestWins(guestWin++);
				}
				this.generalDao.save(m);
			
			// 4 投票成功后  修改 matchData  是2条数据的修改
			MatchPoll mp = new MatchPoll();
			mp.setFavorId(matchId);
			mp.setMatchId(matchId);
			mp.setTime(System.currentTimeMillis());
			mp.setUserId(userId);
			MatchData md = MatchDataHelper.getMatchData(matchId, MatchDataType.POLLS);
			if(md != null){
				List<MatchPoll> list = (List)md.getDataAsList(MatchPoll.LIST_TYPE);
				list.add(mp);
				md.setData(list);
				this.generalDao.save(md);
			}else{
				md = new MatchData(matchId, MatchDataType.POLLS);
				List<MatchPoll> list = new ArrayList<MatchPoll>();
				list.add(mp);
				md.setData(list);
				this.generalDao.save(md);
			}
			// 5 userData的修改
			UserData userData = UserDataHelper.getUserData(userId, UserDataType.RECENT_POLLS);
			if(userData != null){
				List<MatchPoll> list = (List)userData.getDataAsList(MatchPoll.LIST_TYPE);
				list.add(mp);
				userData.setData(list);
				this.generalDao.save(userData);
			}else{
				userData = new UserData(userId, UserDataType.RECENT_POLLS);
				List<MatchPoll> list = new ArrayList<MatchPoll>();
				list.add(mp);
				userData.setData(list);
				this.generalDao.save(userData);
			}
			//发起新鲜事
			Event event = new Event(userId,EventType.POLL,matchId);
			eventService.handleEvent(event);
				return true;
			}else{//我的时间还没有到1个小时
				return false;
			}
		}else{
			//已经结束的PK
			MatchData md = MatchDataHelper.getMatchData(matchId, MatchDataType.ENDMATCH);
			if(md != null){ 
//				List<Long> list = (List)md.getDataAsList(Types.LONG_LIST);
//				list.add(matchId);
//				md.setData(list);
//				this.generalDao.save(md);
			}else{
				md = new MatchData(matchId, MatchDataType.ENDMATCH);
				List<Long> list = new ArrayList<Long>();
				list.add(matchId);
				md.setData(list);
				this.generalDao.save(md);
			}
			// 5 userData的修改
			UserData userData = UserDataHelper.getUserData(userId, UserDataType.RECENT_ENDMATCH);
			if(userData != null){
				List<Long> list = (List)userData.getDataAsList(Types.LONG_LIST);
				if(!list.contains(matchId)){
					list.add(matchId);
					userData.setData(list);
					this.generalDao.save(userData);
				}
			}else{
				userData = new UserData(userId, UserDataType.RECENT_ENDMATCH);
				List<Long> list = new ArrayList<Long>();
				list.add(matchId);
				userData.setData(list);
				this.generalDao.save(userData);
			}
			//发起新鲜事
			Event event = new Event(userId,EventType.END_MATCH,matchId);
			eventService.handleEvent(event);
			
			return false;
		}
	}
	
	@Transactional(readOnly=true)
	public MatchData getMatchData(Long matchId, MatchDataType type) {
		return this.pictureDao.getMatchData(matchId, type);
	}
	@Transactional(readOnly=true)
	public PictureData getPictureData(Long pictureId, PictureDataType type) {
		return this.pictureDao.getPictureData(pictureId, type);
	}
	
	@Autowired
	public void setGeneralDao(GeneralDAO generalDao) {
		this.generalDao = generalDao;
	}
	
	@Autowired
	public void setPictureDao(PictureDao pictureDao) {
		this.pictureDao = pictureDao;
	}
	@Autowired
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	@Autowired
	public void setEventService(EventService eventService) {
		this.eventService = eventService;
	}

}
